// ========================================================
// SUM OF SQUARES
//
// Calculates:
//     1² + 2² + 3² + 4² + 5² = 55
//
// THIS PROGRAM DEMONSTRATES:
//
//   1. Calling a function with JAL.
//   2. Returning from a function with JALR.
//   3. A function calling another function.
//   4. Saving and restoring the return address.
//   5. Passing a function argument in a register.
//   6. Returning a function result in a register.
//   7. Creating loops with BEQ and JAL.
//   8. Squaring a number using repeated addition.
//   9. Accumulating several results into a total.
//  10. Using ADDI with positive and negative values.
//
// REGISTER USE:
//
//   x1  = current return address
//   x5  = current number
//   x6  = accumulated sum
//   x10 = function argument
//   x11 = Square function counter
//   x12 = function result
//   x20 = saved return address
//
// EXPECTED OUTPUT:
//
//   Sum of squares = 55
// ========================================================


start:

        addi  x10, x0, 5          // Calculate sum through 5

        jal   x1, SumSquares       // Call SumSquares function

        cout  << "Sum of squares = " << x12 << endl

        jal   x0, EndProgram       // Skip function code


// --------------------------------------------------------
// SumSquares
//
// Input:
//   x10 = highest number
//
// Output:
//   x12 = sum of the squares
// --------------------------------------------------------

SumSquares:
        add   x20, x1, x0          // Save caller's return address
        add   x5, x10, x0          // Current number = input
        addi  x6, x0, 0            // Sum starts at zero

SumLoop:
        beq   x5, x0, SumComplete  // Stop after processing 1

        add   x10, x5, x0          // Square argument = current number
        jal   x1, Square           // Call Square function

        add   x6, x6, x12          // Add square to total
        addi  x5, x5, -1           // Move to next number

        jal   x0, SumLoop


// --------------------------------------------------------
// Return from SumSquares
// --------------------------------------------------------

SumComplete:
        add   x12, x6, x0          // Place total in return register
        add   x1, x20, x0          // Restore original return address
        jalr  x0, 0(x1)            // Return to main program


// --------------------------------------------------------
// Square
//
// Input:
//   x10 = number to square
//
// Output:
//   x12 = squared value
// --------------------------------------------------------

Square:
        addi  x12, x0, 0           // Result starts at zero
        add   x11, x10, x0         // Counter = input value

SquareLoop:
        beq   x11, x0, SquareReturn

        add   x12, x12, x10        // Result += input value
        addi  x11, x11, -1         // Decrease counter

        jal   x0, SquareLoop

SquareReturn:
        jalr  x0, 0(x1)            // Return to SumSquares

EndProgram:
